<script setup lang="ts">
import {
  NForm,
  NFormItem,
  NInput,
  NButton,
  type DataTableColumns,
  NDataTable,
  useMessage,
  type FormInst,
  NTreeSelect,
  NModal,
  NTag,
  NScrollbar,
  NFlex,
  NImage,
  NEllipsis
} from 'naive-ui'
import { reactive, ref, onMounted, shallowRef, h } from 'vue'
import useRouteReplace from '@/hooks/useRouteReplace'
import { useRoute } from 'vue-router'
import type { DjStat, CollectingDJTableRowModel, CommonSelectOptionModel } from '@/api/batch'
import { sendRequest } from '@/utils/api'
import type { HttpResponse, HttpResponsePagination } from '@/utils/http'
import FixedAction from '@/components/FixedAction.vue'
import BatchInfo from './components/BatchInfo.vue'
import VScope from '@/views/OA/Common/Scope.vue'

// 督交人
interface Contact {
  identifyingId: string
  typeName: string
  parentId: string
  typeCode: string
  deptId: string
  fullId: string
}

const v1 = () => {
  submitFormInst.value?.validate(
    () => {},
    (r) => r.key === 'receiver'
  )
}
const contactsModalVisible = ref(false)
const handleContactsModalSubmit = (v: Contact[]) => {
  submitFormData.receiver = v.map((e) => e.typeName).join(',')
  submitFormData.scopeOrPeopleList = v
  contactsModalVisible.value = false
  v1()
}
const handleDeleteContact = (index: number) => {
  submitFormData.scopeOrPeopleList?.splice(index, 1)
  submitFormData.receiver = submitFormData.scopeOrPeopleList.map((e) => e.typeName).join(',')
  v1()
}

const route = useRoute()
const message = useMessage()
const routeReplace = useRouteReplace(route.query.redirect as string)

const submitFormData = reactive<{
  receiver: string | null
  scopeOrPeopleList: Contact[]
}>({
  receiver: null,
  scopeOrPeopleList: []
})

const submitFormInst = ref<FormInst | null>(null)
const submitLoading = ref(false)
const handleSubmit = () => {
  if (submitLoading.value) return

  if (checkedIds.value.length === 0) {
    message.error('请选择征集品')
    return
  }

  submitFormInst.value?.validate(async (error) => {
    if (error) return

    try {
      submitLoading.value = true
      const [error, res] = await sendRequest({
        module: 'batch',
        api: 'addDjRecord',
        override: {
          data: {
            batchId: route.params.id,
            receiver: submitFormData.receiver,
            items: tableData.value
              .filter(
                (e) => checkedSubItemModels.value.findIndex((c) => c.itemId === e.subItemId) !== -1
              )
              .map((e) => ({
                ...e,
                batchId: route.params.id
              })),
            subItems: checkedSubItemModels.value.map((e) => ({
              ...e,
              batchId: route.params.id
            }))
          }
        }
      })
      if (error) throw error
      if (res.code !== 0) throw new Error(res.msg)
      message.success(res.msg)
      window.flags.flushBatch = true
      routeReplace()
    } catch (error: any) {
      message.error(error.message)
    } finally {
      submitLoading.value = false
    }
  })
}

const djStat = ref({} as DjStat)
const queryDjStat = async () => {
  try {
    const [error, res] = await sendRequest<HttpResponse<DjStat>>({
      module: 'batch',
      api: 'subitemStat',
      override: {
        params: {
          batchId: route.params.id
        }
      }
    })
    if (error) throw error
    if (res.code !== 0) throw new Error(res.msg)
    djStat.value = res.data
  } catch (error) {
    console.error(error)
  }
}

const djStatusOptions = shallowRef<CommonSelectOptionModel[]>([])
const djStatusLoading = ref(false)
const queryDjStatusOptions = async () => {
  try {
    djStatusLoading.value = true
    const [error, res] = await sendRequest<HttpResponse<CommonSelectOptionModel[]>>({
      module: 'batch',
      api: 'djStatusList'
    })
    if (error) throw error
    if (res.code !== 0) throw new Error(res.msg)
    djStatusOptions.value = res.data
  } catch (error) {
    console.log(error)
  } finally {
    djStatusLoading.value = false
  }
}

const subItemTypeOptions = shallowRef<any[]>([])
const subItemTypeLoading = ref(false)
const querySubItemTypeOptions = async () => {
  try {
    subItemTypeLoading.value = true
    const [error, res] = await sendRequest({
      module: 'collectProcess',
      api: 'listTreeAll',
      override: {
        params: {
          statusCode: 'A4901'
        }
      }
    })
    if (error) throw error
    if (res.code !== 0) throw new Error(res.msg)
    emptyChildrenToNull(res.data)
    subItemTypeOptions.value = res.data
  } catch (error) {
    console.log(error)
  } finally {
    subItemTypeLoading.value = false
  }
}
const emptyChildrenToNull = (e: any[]) => {
  for (const option of e) {
    if (option.childList && option.childList.length === 0) {
      option.childList = null
    }
    if (!option.childList) continue
    emptyChildrenToNull(option.childList)
  }
}

const formData = reactive({
  itemName: null,
  itemType: null,
  djStatus: null
})
const checkedIds = ref<number[]>([])
const checkedSubItemModels = shallowRef<CollectingDJTableRowModel[]>([])
const checkedRootModels = shallowRef<CollectingDJTableRowModel[]>([])
const handleUpdateCheckedIds: any = (ids: number[], rows: CollectingDJTableRowModel[]) => {
  checkedIds.value = ids
  checkedSubItemModels.value = []
  checkedRootModels.value = []

  rows.forEach((r) => {
    const root = tableData.value.findIndex((e) => e.subItemId === r.subItemId) !== -1
    if (root) {
      // checkedRootModels.value.push(r)
    } else {
      checkedSubItemModels.value.push(r)
    }
  })
}
const isDefineSubItems = (e: CollectingDJTableRowModel) => e.subItems && e.subItems.length
const tableData = ref<CollectingDJTableRowModel[]>([])
const tableLoading = ref(false)
const columns: DataTableColumns<CollectingDJTableRowModel> = [
  {
    type: 'selection'
  },
  {
    title: '序号',
    key: 'index',
    width: 80,
    align: 'center',
    render: (e, index) => {
      if (!e.subItems) return null
      return index + 1
    }
  },
  {
    title: '征集品编码',
    key: 'subItemCode'
  },
  {
    title: '征集品名称',
    key: 'itemName'
  },
  {
    title: '类型',
    key: 'itemType'
  },
  {
    title: '数量',
    key: 'num',
    align: 'center',
    render: (e) => {
      if (isDefineSubItems(e)) return e.subItems.length
      return '1'
    }
  },
  {
    title: '年代',
    key: 'years',
    align: 'center'
  },
  {
    title: '备注',
    key: 'remark',
    align: 'center',
    render({ remark }) {
      return h(
        NEllipsis,
        { lineClamp: 2 },
        {
          default: () => remark,
          tooltip: () => {
            return h('div', { style: 'width: 200px' }, { default: () => remark })
          }
        }
      )
    }
  },
  {
    title: '图片',
    key: 'imageIds',
    render({ _imageFiles }) {
      if (!_imageFiles) return
      return h(
        NFlex,
        {},
        {
          default: () =>
            _imageFiles.map((e) =>
              h(NImage, {
                src: e.path,
                width: 50
              })
            )
        }
      )
    }
  }
]
const queryTableData = async () => {
  try {
    tableLoading.value = true
    const [error, res] = await sendRequest<HttpResponsePagination<CollectingDJTableRowModel>>({
      module: 'batch',
      api: 'collectingDJList',
      override: {
        params: {
          batchId: route.params.id,
          djStatusCode: formData.djStatus || null,
          itemName: formData.itemName || null,
          itemTypeCode: formData.itemType || null,
          limit: 10000000
        }
      }
    })
    if (error) throw error
    if (res.code !== 0) throw new Error(res.msg)
    res.data.list.forEach((e) => (e.subItemId = e.itemId))
    res.data.list.forEach((e) => (e.subItemCode = e.itemCode))
    tableData.value = res.data.list
    checkedIds.value = []

    tableData.value.forEach((item) => {
      if (!item.imageIds) return
      sendRequest({
        module: 'upload',
        api: 'list',
        override: {
          params: {
            ids: item.imageIds
          }
        }
      }).then(([error, res]) => {
        if (error || res.code !== 0) return
        item._imageFiles = res.data
      })
    })
  } catch (error) {
    console.error(error)
  } finally {
    tableLoading.value = false
  }
}

onMounted(() => {
  queryDjStat()
  queryTableData()
  queryDjStatusOptions()
  querySubItemTypeOptions()
})
</script>

<template>
  <div class="dj">
    <BatchInfo />

    <div class="br"></div>

    <div class="dj-title">督交人</div>
    <NForm
      ref="submitFormInst"
      label-placement="left"
      require-mark-placement="left"
      class="dj-card"
      :model="submitFormData"
    >
      <NFormItem
        label="选择督交人："
        path="receiver"
        :rule="{
          key: 'receiver',
          required: true,
          message: '督交人为必填项，请选择',
          trigger: ['change', 'blur']
        }"
      >
        <div class="contacts">
          <NButton
            type="primary"
            ghost
            @click="contactsModalVisible = true"
          >
            选择督交人
          </NButton>

          <NScrollbar style="max-height: 210rem">
            <div
              v-show="submitFormData.scopeOrPeopleList?.length"
              class="contacts-content"
            >
              <NTag
                v-for="(contact, index) in submitFormData.scopeOrPeopleList"
                @close="handleDeleteContact(index)"
                :key="index"
                closable
                :color="{ color: '#ffffff' }"
                style="justify-content: space-between; gap: 0 10rem"
              >
                {{ contact.typeName }}
              </NTag>
            </div>
          </NScrollbar>
        </div>
      </NFormItem>
    </NForm>

    <div
      v-if="false"
      class="br"
    ></div>

    <div
      v-if="false"
      class="dj-title"
    >
      点交
    </div>
    <div
      v-if="false"
      class="dj-card dj-count"
    >
      <div class="dj-count__item">
        <img src="@/assets/images/all-collection.png" />
        <span>
          <strong>{{ djStat.total }}</strong>
          件
        </span>
        <span>所有征集品</span>
      </div>
      <div class="dj-count__item">
        <img src="@/assets/images/djed.png" />
        <span>
          <strong>{{ djStat.clicked }}</strong>
          件
        </span>
        <span>已点交</span>
      </div>
      <div class="dj-count__item">
        <img src="@/assets/images/undj.png" />
        <span>
          <strong>{{ djStat.notClicked }}</strong>
          件
        </span>
        <span>未点交</span>
      </div>
      <div class="dj-count__item">
        <img src="@/assets/images/registered.png" />
        <span>
          <strong>{{ djStat.temporary }}</strong>
          件
        </span>
        <span>暂存</span>
      </div>
    </div>

    <div
      class="dj-card"
      style="padding: 0 20rem"
    >
      <NForm
        label-placement="left"
        :show-feedback="false"
        inline
        style="background-color: #ebeceb; padding: 15rem 20rem 20rem"
        @keydown.enter="queryTableData"
      >
        <NFormItem label="征集品名称：">
          <NInput
            v-model:value="formData.itemName"
            placeholder="请输入"
            clearable
          />
        </NFormItem>
        <NFormItem label="类型：">
          <NTreeSelect
            :loading="subItemTypeLoading"
            :options="subItemTypeOptions"
            children-field="childList"
            key-field="classificationCode"
            label-field="classificationName"
            v-model:value="formData.itemType"
            placeholder="请选择"
            clearable
            style="width: 150rem"
          />
        </NFormItem>
        <!-- <NFormItem label="点交状态：">
          <NSelect
            :loading="djStatusLoading"
            :options="(djStatusOptions as unknown as SelectOption[])"
            v-model:value="formData.djStatus"
            label-field="name"
            placeholder="请选择"
            clearable
            style="width: 150rem"
          />
        </NFormItem> -->
        <NFormItem>
          <NButton
            color="#5FB17F"
            ghost
            style="width: 100rem"
            @click="queryTableData"
          >
            查询
          </NButton>
        </NFormItem>
      </NForm>
    </div>

    <NDataTable
      :loading="tableLoading"
      :data="tableData"
      :columns="columns"
      children-key="subItems"
      :row-key="(row) => row.subItemId"
      :checked-row-keys="checkedIds"
      @update-checked-row-keys="handleUpdateCheckedIds"
      max-height="200rem"
      class="dj-card"
      style="padding-top: 0"
    />
  </div>

  <NModal
    :auto-focus="false"
    v-model:show="contactsModalVisible"
    @close="contactsModalVisible = false"
  >
    <VScope
      @close="contactsModalVisible = false"
      @scopeSubmit="handleContactsModalSubmit"
      :default-list="submitFormData.scopeOrPeopleList"
      flat
    />
  </NModal>

  <FixedAction>
    <div class="dj-buttons">
      <NButton
        color="#999999"
        ghost
        :disabled="submitLoading"
        @click="routeReplace"
        style="width: 78px; height: 34px"
      >
        取消
      </NButton>

      <NButton
        color="#5FB17F"
        :disabled="submitLoading"
        :loading="submitLoading"
        @click="handleSubmit"
        style="width: 78px; height: 34px"
      >
        确定
      </NButton>
    </div>
  </FixedAction>
</template>

<style scoped lang="scss">
.dj {
  min-height: 100%;
  padding: 15rem 0 110rem;
  background-color: #f0efee;

  :deep(.n-data-table__pagination) {
    justify-content: flex-start;
  }

  .br {
    position: relative;
    width: 100%;
    padding: 30rem 0;

    &::after {
      content: '';
      position: absolute;
      width: 100%;
      top: 50%;
      left: 0;
      border-top: 1px dotted #bc9e70;
      transform: translateY(-50%);
    }
  }

  .contacts {
    display: flex;
    flex-direction: column;
    gap: 10rem 0;

    .n-button {
      max-width: 126rem;
    }

    .contacts-content {
      display: grid;
      grid-template-columns: repeat(5, auto);
      gap: 10rem;
      padding: 15rem;
      background-color: #fff;
    }
  }

  .dj-card {
    padding: 20rem;
    background-color: #e1e1e1;
  }

  .n-form.grid {
    display: grid;
    grid-template-columns: repeat(2, 1fr);
    gap: 16rem 60rem;
  }

  .dj-title {
    font-size: 26rem;
    margin-bottom: 30rem;
    color: #048c5e;
    line-height: 1;
  }

  .dj-count {
    display: flex;
    justify-content: center;
    gap: 0 16rem;
    background-color: #e1e1e1;

    &__item {
      display: grid;
      gap: 10rem 17rem;
      justify-content: center;
      grid-template-areas:
        'icon count'
        'icon label';
      flex: 1;
      padding: 18rem;
      background-color: #ebeceb;

      strong {
        font-size: 24rem;
      }

      img {
        display: block;
        grid-area: icon;
        width: 48rem;
        height: 48rem;
        margin-bottom: 10rem;
        align-self: end;
      }

      span:first-of-type {
        grid-area: count;
      }

      span:last-of-type {
        grid-area: label;
      }
    }
  }
}

.dj-buttons {
  width: 100%;
  display: flex;
  align-items: center;
  justify-content: center;
  gap: 0 16rem;

  .n-button {
    width: 100rem;
    height: 50rem;
  }
}
</style>
